package schedule;

import java.util.ArrayList;

import plan.Plan;
import auftrag.Auftrag;
import auftrag.Produkt;
import auftrag.Ressource;

public class IterateVariants implements ISchedule {

	@Override
	public Plan makePlan(ArrayList<?> pAuftragList,
			ArrayList<Ressource> pRessourceList) {
		//Sortiere die Aufträge nach EDF, dann nach Priorität
		Plan p = new Plan();
		ArrayList<Produkt> prodList = new ArrayList<Produkt>();
		if(Auftrag.class.isInstance(pAuftragList.get(0))){
			Auftrag aufAuftrag;
			ArrayList<Auftrag> arrSortAuftrag = new ArrayList<Auftrag>();
			for (int intIndexa = 0; intIndexa < pAuftragList.size(); intIndexa++) {
				aufAuftrag = (Auftrag) pAuftragList.get(intIndexa);
				if (arrSortAuftrag.isEmpty()) {
					arrSortAuftrag.add(aufAuftrag);
				} else {
					for (int intIndexb = 0; intIndexb < arrSortAuftrag.size(); intIndexb++) {
						if (aufAuftrag.getDeadline() < arrSortAuftrag
								.get(intIndexb).getDeadline()) {
							arrSortAuftrag.add(intIndexb, aufAuftrag);
							intIndexb = arrSortAuftrag.size();
						}
						else if (aufAuftrag.getDeadline() == arrSortAuftrag.get(
								intIndexb).getDeadline()
								&& aufAuftrag.getPriority() > arrSortAuftrag.get(
										intIndexb).getPriority()) {
							arrSortAuftrag.add(intIndexb, aufAuftrag);
							intIndexb = arrSortAuftrag.size();
						}
						else if((intIndexb+1) >= arrSortAuftrag.size() ){
							arrSortAuftrag.add(aufAuftrag);
							intIndexb = arrSortAuftrag.size();
						}
					}
				}
			}
			for(Auftrag a : arrSortAuftrag){
				prodList.addAll(a.getAuftragProdukte());
			}
		}
		//SimplePlan fügt einfach eine Produktliste mit gewählten Varianten der Reihe nach in die Maschinen ein
		p = new SimplePlan().makePlan(prodList, pRessourceList);
		double t = 10;
		int quality = 0;
		//solange die Qualität nicht 0 ist und t > 0.1
		while(p.getQuality() > 0 && t > 0.1){
			Plan pNeighbour;
			//alte Qualität
			quality = p.getQuality();
			//bestimme zufälliges Produkt
			int nProd = (int) (Math.random()*prodList.size());
			Produkt prodTemp =  prodList.get(nProd);
			
			//bestimme alte Variante für Rollback
			int oldVariant = prodTemp.getProduktVariante().indexOf(prodTemp.getChosenVariante());
			
			//wähle neue Variante
			prodTemp.chooseVariant(oldVariant+1, false);
			
			for(Ressource r : pRessourceList)
				r.clear();
			
			//neuer Plan
			pNeighbour = new SimplePlan().makePlan(prodList, pRessourceList);
			
			//falls neuer Plan besser: behalten
			if(pNeighbour.getQuality() < quality + t){
				p = pNeighbour;
				
			//sonst: Rollback, t verkleinern
			} else {
				prodTemp.chooseVariant(oldVariant, false);
				t=t*0.995;
				
				for(Ressource r : pRessourceList)
					r.clear();
				
				p = new SimplePlan().makePlan(prodList, pRessourceList);
			}
			
			System.out.println("Quality:"+p.getQuality()+"\tt:"+t);
		}
		
		return p;
	}

}
